/*
 *	OpenSource code and fragments by avocado systems, Marcus Fuhrmeister
 *
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions
 *	are met:
 *  
 *		* Redistribution of source code must retain the above OpenSource comment,
 *		this list of conditions and the following disclaimer.
 * 
 *		* Redistribution in binary form must reproduce the above OpenSource comment,
 *		this list of conditions and the following disclaimer in the
 *		documentation and/or other materials provided with the distribution.
 * 
 *	Neither the name of 'avocaod systems, Marcus Fuhrmeister' or the
 *	names of contributors may be used to endorse or promote products derived
 *	from this software without specific prior written permission.
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 */
package de.fuhrmeister.browserchooser.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ListIterator;

import de.fuhrmeister.util.ConfigManager;
import de.fuhrmeister.util.Tools;

/**
 * Model factory class.
 * Helper functions, e.g. sort, load and save the model.
 * 
 * @date 16.10.2008
 * @author Marcus Fuhrmeister
 */
public class ModelFactory {

	private static ArrayList<BrowserModel> browserArrayList = new ArrayList<BrowserModel>();

	/**
	 * Sorts the browser model list.
	 */
	private static void sortModels() {
		final  Object[] a = browserArrayList.toArray();
		Arrays.sort(a);
		final ListIterator<BrowserModel> iList = browserArrayList.listIterator();
		for (int counter = 0; counter < a.length; counter++) {
			iList.next();
			((BrowserModel) a[counter]).setID(counter + 1);
			iList.set((BrowserModel) a[counter]);
		}
	}

	/**
	 * Deserializes the models from the model file.
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static void load() throws Exception {
		browserArrayList = (ArrayList<BrowserModel>) Tools.fileManager.deserialize(Tools.configMng.getConfiguration(ConfigManager.MODEL_FOLDER) + System.getProperty("file.separator") + Tools.configMng.getConfiguration(ConfigManager.MODEL_FILE));
	}

	/**
	 * If the browser model list is not empty, it calls to sort the models and calls to serialize it.
	 */
	public static void save() {
		if (!browserArrayList.isEmpty()) {
			ModelFactory.sortModels();
			Tools.fileManager.serialize(browserArrayList, Tools.configMng.getConfiguration(ConfigManager.MODEL_FOLDER) + System.getProperty("file.separator") + Tools.configMng.getConfiguration(ConfigManager.MODEL_FILE));
		} else {
			Tools.fileManager.erase(Tools.configMng.getConfiguration(ConfigManager.MODEL_FOLDER) + System.getProperty("file.separator") + Tools.configMng.getConfiguration(ConfigManager.MODEL_FILE));
		}
	}

	/**
	 * Indicates if the browser model list is not empty.
	 * 
	 * @return true if the browser model list is not empty
	 */
	public static boolean modelExists() {
		return !browserArrayList.isEmpty();
	}

	/**
	 * Returns the browser model count.
	 * 
	 * @return the browser model count
	 */
	public static int getBrowserModelCount() {
		return browserArrayList.size();
	}

	/**
	 * Returns the browser models within an iterator.
	 * 
	 * @return the browser models within an iterator
	 */
	public static Iterator<BrowserModel> getBrowserModels() {
		return browserArrayList.iterator();
	}

	/**
	 * Returns the browser model for the given id.
	 * 
	 * @param id
	 * @return
	 */
	public static BrowserModel getBrowserModel(final int id) {
		for (int count = 0; count < browserArrayList.size(); count++) {
			if (id == browserArrayList.get(count).getID()) {
				return browserArrayList.get(count);
			}
		}
		return null;
	}

	/**
	 * Adds the given <code>BrowserModel</code> to the browser model list.
	 * 
	 * @param bm the <code>BrowserModel</code> to add
	 */
	public static void addBrowserModel(final BrowserModel bm) {
		browserArrayList.add(bm);
	}

	/**
	 * Updates the browser model list with the given list. 
	 * 
	 * @param aList the new browser model list
	 */
	public static void update(final ArrayList<BrowserModel> aList) {
		browserArrayList = aList;
	}

	/**
	 * Replaces the model with the given <code>BrowserModel</code>,
	 * if the id is the same, or calls to add the given <code>BrowserModel</code>
	 * to the browser model list.
	 * 
	 * @param bm
	 */
	public static void updateBrowserModel(final BrowserModel bm) {
		for (int count = 0; count < browserArrayList.size(); count++) {
			if (bm.getID() == browserArrayList.get(count).getID()) {
				browserArrayList.set(count, bm);
				return;
			}
		}
		addBrowserModel(bm);
	}

	/**
	 * Clears the browser model list if only one model is in the list and calls to save,
	 * or removes the model with the id of the given <code>BrowserModel</code> from the list.
	 * 
	 * @param bm the model to delete
	 */
	public static void deleteBrowserModel(final BrowserModel bm) {
		if (browserArrayList.size() == 1) {
			browserArrayList.clear();
			save();
		} else {
			for (int count = 0; count < browserArrayList.size(); count++) {
				if (bm.getID() == browserArrayList.get(count).getID()) {
					browserArrayList.remove(count);
				}
			}
		}
	}

	/**
	 * Calls to check if the model file exists.
	 * 
	 * @return true if the model file exists
	 */
	public static boolean modelFileExists() {
		return Tools.fileManager.exists(Tools.configMng.getConfiguration(ConfigManager.MODEL_FOLDER) + System.getProperty("file.separator") + Tools.configMng.getConfiguration(ConfigManager.MODEL_FILE));
	}
}